<?php
declare(strict_types=1);

namespace App\Middleware;

use App\Helper\ApiHelper;
use App\Helper\JwtHelper;
use App\Helper\RequestHelper;
use App\Model\AdminUser;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Utils\Codec\Json;
use Hyperf\Utils\Context;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class AdminMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $moduleAndAction = RequestHelper::getAdminModule($request);
        if (is_null($moduleAndAction)) {
            return $handler->handle($request);
        }
//        if ($moduleAndAction != '管理后台:系统设置:通用@查看图片' && !RequestHelper::isAjax($request)) {
//            return Context::get(ResponseInterface::class)->withStatus(404);
//        }
        $jwtData = JwtHelper::decodeWithRequest(JwtHelper::ADMIN_JWT_TOKEN, $request);
        if (!$jwtData || time() - $jwtData->iat > 864000) { // 未登录，或登录状态超过10天
            return self::json('请登录！');
        }
        $userModel = AdminUser::find($jwtData->data->id);
        if (!$userModel) { // 用户已被删除
            return self::json('请登录！');
        }
        if ($userModel->id == AdminUser::SUPER_ADMIN_ID) { // 超级管理员
            unset($jwtData, $userModel);
            return $handler->handle($request);
        }
        $adminRole = $userModel->admin_role;
        if (!$adminRole || !in_array($moduleAndAction, $adminRole->module_available)) {
            return self::json('无权访问！');
        }
        unset($jwtData, $userModel, $adminRole);
        return $handler->handle($request);
    }

    private static function json(string $msg)
    {
        $body = new SwooleStream(Json::encode(ApiHelper::genErrorData($msg)));
        return Context::get(ResponseInterface::class)
            ->withAddedHeader('content-type', 'application/json; charset=utf-8')
            ->withBody($body);
    }
}
